package com.my.mvvmrapid.view;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.Space;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.widget.NestedScrollView;
import androidx.viewpager2.widget.ViewPager2;

import com.my.mvvmrapid.R;
import com.my.mvvmrapid.ui.main.fragment.homeshop.adapter.HomeShopNavigatorAdapter;
import com.zhongjh.mvvmrapid.utils.AnimUtil;
import com.zhongjh.mvvmrapid.utils.DisplayMetricsUtil;
import com.zhongjh.mvvmrapid.utils.StatusBarUtil;

import net.lucode.hackware.magicindicator.MagicIndicator;
import net.lucode.hackware.magicindicator.buildins.commonnavigator.CommonNavigator;

/**
 * Created by zhongjh on 2021/4/12.
 * 非常感谢该篇文章：https://baiyuliang.blog.csdn.net/article/details/108168917
 */
@SuppressWarnings("ALL")
public class HomeShopScrollView extends NestedScrollView {

    private ViewPager2 mViewPager2;
    private HomeShopLinearLayout mHomeShopLinearLayout;
    private ImageView mImageView;
    private Space mSpace;
    private TextView mTvRefreshState;
    private MagicIndicator mMagicIndicator;

    private int marginTop, paddingTop;
    private static final float REFRESH_RATIO = 2.0f; // 下拉系数（阻尼系数）,越大下拉灵敏度越低
    private static final int AD_START_SCROLL_DISTANCE = 100; // 广告图开始滑动的距离阈值（超过该值时才开始滑动）
    private static final int REFRESHL_DISTANCE = 150; // 刷新距离阈值（超过该值时才开始刷新）

    private boolean mIsInterceptTouch; // 拦截触摸
    private boolean mIsInterceptScroll; // 是否正在拦截滚动
    private boolean mDisable; // 判断是否启动滑动

    private float mStartY = -1, // 手指起始触摸位置
            mOffsetY, // 手指移动距离（真实移动距离）
            mOldDistance; // 经过下拉系数换算的最终距离(实际使用的距离，也就是tab栏移动的距离)
    private float mMaxOffsetY; //下拉最大距离
    private int mScrollY; //整个界面向上滑动的距离
    private int mAdScrollDistance;//广告图移动高度

    private static final int REFRESH_DONE = 0;//刷新完成/初始状态
    private static final int PULL_TO_REFRESH = 1;//下拉刷新
    private static final int RELEASE_TO_REFRESH = 2;//释放刷新
    private static final int REFRESHING = 3;//刷新中

    private static int REFRESH_STATUS = PULL_TO_REFRESH;

    public HomeShopScrollView(@NonNull Context context) {
        super(context);
    }

    public HomeShopScrollView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public HomeShopScrollView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 添加关联的view
     */
    public void setView(ViewPager2 viewPager2, HomeShopLinearLayout homeShopLinearLayout,
                        ImageView imageView, Space space, TextView tvRefreshState, MagicIndicator magicIndicator) {
        this.mViewPager2 = viewPager2;
        this.mHomeShopLinearLayout = homeShopLinearLayout;
        this.mImageView = imageView;
        this.mSpace = space;
        this.mTvRefreshState = tvRefreshState;
        this.mMagicIndicator = magicIndicator;
        setOverScrollMode(OVER_SCROLL_NEVER); // 设置无阴影
        mImageView.setImageAlpha(0); // 图片设置完全透明
        marginTop = -DisplayMetricsUtil.dip2px(320);
        paddingTop = StatusBarUtil.getStatusBarHeight(getResources());
        homeShopLinearLayout.setPadding(0, paddingTop, 0, 0);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        mScrollY = t;
    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        if (!mDisable && !mIsInterceptScroll) {
            super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
        }
    }

    /**
     * 整体思路：
     * 在ACTION_MOVE中，记录Y值的移动距离和最大距离值
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mDisable) {
            return true;
        }
        // 先走的是HomeShopLinearLayou的OnTouch，所以从HomeShopLinearLayou取startY最准确
        mStartY = mHomeShopLinearLayout.getStartY() == 0 ? ev.getRawY() : mHomeShopLinearLayout.getStartY();
        switch (ev.getAction()) {
            case MotionEvent.ACTION_MOVE:
                // 触摸事件 以及 正在刷新时 禁止MOVE
                if (mIsInterceptTouch || REFRESH_STATUS == REFRESHING) {
                    return true;
                }
                // 这一步为了解决正在刷新时，手指又下拉，导致刷新完成时立马又自动下拉到了手指位置
                // 只要判断顶层的mHomeShopLinearLayout的Y值是0就直接返回
                if (mStartY != 0 && mHomeShopLinearLayout.getStartY() == 0) {
                    return true;
                }
                // 如果是向上滑动，则不处理
                if (mMaxOffsetY <= 0 && mScrollY > 0) {
                    return super.onTouchEvent(ev);
                }
                // 记录手指移动距离
                mOffsetY = ev.getRawY() - mStartY;
                // 记录手指移动的最大值
                if (mOffsetY > mMaxOffsetY) {
                    mMaxOffsetY = mOffsetY;
                }
                // mScrollY==0代表是上拉，mOffsetY是下拉距离值
                if (mScrollY == 0 && mOffsetY > 0) {
                    // 标记正在滚动
                    mIsInterceptScroll = true;
                    // 根据下拉系数，换算成最终距离
                    float distance = mOffsetY / REFRESH_RATIO;
                    if (Math.abs(distance - mOldDistance) < 1) {
                        return super.onTouchEvent(ev);
                    }
                    // 设置成刷新状态
                    REFRESH_STATUS = PULL_TO_REFRESH;
                    if (distance >= AD_START_SCROLL_DISTANCE) {
                        ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) mSpace.getLayoutParams();
                        if (layoutParams.bottomMargin > 0) {
                            Log.d("tag", "layoutParams.topMargin:" + layoutParams.topMargin);
                            mAdScrollDistance = (int) (distance - AD_START_SCROLL_DISTANCE);
                            layoutAd(marginTop + mAdScrollDistance);
                        }
                    }
                    if (distance > REFRESHL_DISTANCE) {
                        REFRESH_STATUS = RELEASE_TO_REFRESH;
                        mTvRefreshState.setText(getResources().getString(R.string.release_the_refresh));
                    } else {
                        REFRESH_STATUS = PULL_TO_REFRESH;
                        mTvRefreshState.setText(getResources().getString(R.string.pull_to_refresh));
                    }
                    int alpha = distance > 0 && distance * 2 <= 255 ? (int) distance * 2 : 255;
                    if (onPullListener != null) {
                        onPullListener.onPull(255 - alpha);
                    }
                    mImageView.setImageAlpha(alpha);
                    // mLLContent随着滑动而设置paddingTop
                    mHomeShopLinearLayout.setPadding(0, (int) (paddingTop + distance), 0, 0);
                    mOldDistance = distance;
                    return true;
                } else if (mScrollY == 0 && mMaxOffsetY > 0 && mOffsetY <= 0) {
                    // 复位后禁止再次滑动
                    layoutAd(marginTop);
                    mImageView.setImageAlpha(0);
                    mHomeShopLinearLayout.setPadding(0, paddingTop, 0, 0);
                    mIsInterceptTouch = true;
                    mIsInterceptScroll = true;
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
                mIsInterceptTouch = false;
                if (mMaxOffsetY > 0) {
                    if (REFRESH_STATUS == RELEASE_TO_REFRESH) {
                        // 释放刷新
                        disableTab();
                        mIsInterceptTouch = true;
                        REFRESH_STATUS = REFRESHING; // 刷新中
                        mHomeShopLinearLayout.setRefreshing(true);
                        AnimUtil.start(mAdScrollDistance, 200, new AnimUtil.OnAnimListener() {
                            @Override
                            public void onUpdate(int value) {
                                layoutAd(marginTop + mAdScrollDistance - value);
                                mHomeShopLinearLayout.setPadding(0, (int) (paddingTop + mOldDistance - value), 0, 0);
                            }

                            @Override
                            public void onEnd() {
                                mTvRefreshState.setText(getResources().getString(R.string.is_refreshing));
                                reset();
                                if (onPullListener != null) {
                                    onPullListener.onPull(0);
                                    onPullListener.onRefresh();
                                }
                            }
                        });
                    } else {
                        // 没有触发刷新，直接复位
                        if (mOffsetY <= 0) {
                            // 手指松开时如果已经滑动到顶部，则不需要再执行动画
                            resetAll();
                        } else {
                            AnimUtil.start((int) mOldDistance, 150, new AnimUtil.OnAnimListener() {
                                @Override
                                public void onUpdate(int value) {
                                    if (mAdScrollDistance > 0 && value <= mAdScrollDistance) {
                                        layoutAd(marginTop + mAdScrollDistance - value);
                                    }
                                    mHomeShopLinearLayout.setPadding(0, paddingTop + (int) (mOldDistance - value), 0, 0);
                                }

                                @Override
                                public void onEnd() {
                                    resetAll();
                                }
                            });
                        }
                    }
                }

                break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 复位所有包括view
     */
    private void resetAll() {
        mTvRefreshState.setText(getResources().getString(R.string.pull_to_refresh));
        mIsInterceptTouch = false;
        mHomeShopLinearLayout.setRefreshing(false);
        mIsInterceptScroll = false;
        REFRESH_STATUS = REFRESH_DONE;
        layoutAd(marginTop);
        mImageView.setImageAlpha(0);
        if (onPullListener != null) {
            onPullListener.onPull(255);
        }
        mHomeShopLinearLayout.setPadding(0, paddingTop, 0, 0);
        reset();
    }

    /**
     * 随着滑动修改imageView的marginTop
     */
    private void layoutAd(int marginTop) {
        Log.d("tag", "marginTop:" + marginTop);
        ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) mSpace.getLayoutParams();
        layoutParams.bottomMargin = -marginTop;
        mSpace.setLayoutParams(layoutParams);
    }

    /**
     * 重置
     */
    void reset() {
        mOffsetY = 0;
        mScrollY = 0;
        mAdScrollDistance = 0;
        mOldDistance = 0;
        mMaxOffsetY = 0;
    }

    /**
     * 设置是否禁用
     */
    public void setDisable(boolean disable) {
        this.mDisable = disable;
    }

    /**
     * 禁止tab点击事件（正在刷新时禁止）
     */
    private void disableTab() {
        ((HomeShopNavigatorAdapter) ((CommonNavigator) mMagicIndicator.getNavigator()).getAdapter()).disable();
    }

    /**
     * 启用tab点击事件
     */
    private void enableTab() {
        ((HomeShopNavigatorAdapter) ((CommonNavigator) mMagicIndicator.getNavigator()).getAdapter()).enable();
    }


    OnPullListener onPullListener;

    /**
     * 刷新事件
     */
    public interface OnPullListener {

        /**
         * 当前进度
         */
        void onPull(int alpha);

        /**
         * 刷新
         */
        void onRefresh();
    }

    public void setOnPullListener(OnPullListener onPullListener) {
        this.onPullListener = onPullListener;
    }

    /**
     * 刷新完成
     */
    public void refreshFinish() {
        AnimUtil.start(AD_START_SCROLL_DISTANCE, 100, new AnimUtil.OnAnimListener() {
            @Override
            public void onUpdate(int value) {
                mHomeShopLinearLayout.setPadding(0, paddingTop + AD_START_SCROLL_DISTANCE - value, 0, 0);
            }

            @Override
            public void onEnd() {
                resetAll();
                enableTab();
            }
        });
    }


}
